package com.kun.video.ui.progress;

import com.kun.video.ui.ComponentUtil;
import com.kun.video.ui.KunComponent;
import com.kun.video.ui.RenderStrategy;
import javafx.animation.Interpolator;
import javafx.animation.Transition;
import javafx.beans.value.ChangeListener;
import javafx.scene.Parent;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.paint.*;
import javafx.util.Duration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Optional;

/**
 * 高性能可扩展进度条基类，支持平滑动画和自定义渲染策略
 * 如果需要更复杂的样式（如动态效果、阴影等），可以通过实现 {@link RenderStrategy} 接口来自定义渲染逻辑。
 *
 * @author gzc
 */
public class KunProgressBar extends ProgressBar implements KunComponent {
    private static final Logger log = LoggerFactory.getLogger(KunProgressBar.class);
    private static final String STYLE_CLASS = "kun-progress-bar";
    /**
     * 动画持续时间（毫秒），设置为 0 表示无动画
     */
    private final Duration ANIMATION_DURATION = Duration.millis(0);
    /**
     * 默认插值器，用于控制动画过渡效果
     */
    private final Interpolator DEFAULT_INTERPOLATOR = Interpolator.EASE_BOTH;
    /**
     * 当前动画对象，用于管理进度条的动画
     */
    protected Transition currentAnimation;
    /**
     * 填充颜色或渐变
     */
    protected Paint fillPaint;
    /**
     * 渲染策略接口，用于自定义绘制逻辑
     */
    protected RenderStrategy renderStrategy;
    /**
     * 进度条文字
     */
    protected Label progressLabel;

    public KunProgressBar() {
        this(0.0D, null, DEFAULT_RENDER_STRATEGY);
    }

    /**
     * 基础构造器
     *
     * @param initialProgress 初始进度值 (0.0-1.0)
     * @param renderStrategy  自定义渲染策略
     */
    public KunProgressBar(double initialProgress, Label progressLabel, RenderStrategy renderStrategy) {
        super(initialProgress);
        this.renderStrategy = renderStrategy;
        this.progressLabel = Optional.ofNullable(progressLabel).orElse(new Label("0%"));
        initialize();
    }


    @Override
    public Parent getNode() {
        return this;
    }

    @Override
    public String getStyleName() {
        return STYLE_CLASS;
    }

    @Override
    public void initLayout() {

    }

    @Override
    public void initDimensions() {
    }

    @Override
    public void reactiveDimensions(double width, double height) {

    }

    private final ChangeListener<Number> progressChangeListener = (obs, ov, nv) -> {
        int intValue = BigDecimal.valueOf(nv.doubleValue()).multiply(BigDecimal.valueOf(100))
                .setScale(0, RoundingMode.HALF_UP).intValue();
        progressLabel.setText(intValue + "%");
        // 如果当前有动画正在运行，则停止它
        if (currentAnimation != null) {
            currentAnimation.stop();
        }
        // 创建新的动画
        currentAnimation = new Transition() {
            {
                // 设置动画持续时间
                setCycleDuration(ANIMATION_DURATION);
                // 设置插值器
                setInterpolator(DEFAULT_INTERPOLATOR);
            }

            @Override
            protected void interpolate(double frac) {
                // 根据插值计算当前进度值
                setProgress(interpolateProgress(ov.doubleValue(), nv.doubleValue(), frac));
            }
        };
        // 播放动画
        currentAnimation.play();
    };

    @Override
    public void initListeners() {
        ComponentUtil.weakChangeListener(progressProperty(), progressChangeListener);
    }

    /**
     * 资源释放
     */
    @Override
    public void dispose() {
        styleProperty().unbind();
        ComponentUtil.removeWeakListener(progressProperty(), progressChangeListener);
    }

    @Override
    public void initData() {

    }

    /**
     * 插值计算进度值
     *
     * @param start    起始进度值
     * @param end      结束进度值
     * @param fraction 插值因子 (0.0-1.0)
     * @return 插值后的进度值
     */
    private double interpolateProgress(double start, double end, double fraction) {
        return start + (end - start) * fraction;
    }

    /**
     * 自定义绘制实现
     * <p>
     * 在此方法中，根据当前进度值和渲染策略绘制进度条。
     */
    @Override
    protected void layoutChildren() {
        super.layoutChildren();
        // 创建 Canvas 用于绘制
        Canvas canvas = new Canvas(getWidth(), getHeight());
        GraphicsContext gc = canvas.getGraphicsContext2D();
        // 应用自定义渲染策略
//        if (renderStrategy != null) {
            renderStrategy.render(canvas, getWidth(), getHeight(), getProgress());
//        } else {
//            // 使用默认渲染逻辑
//            renderDefault(gc, getWidth(), getHeight());
//        }
        // 将 Canvas 添加到场景图中
        getChildren().setAll(canvas);
    }

    /**
     * 设置渲染策略
     *
     * @param renderStrategy 渲染策略实现
     */
    public void setRenderStrategy(RenderStrategy renderStrategy) {
        this.renderStrategy = renderStrategy;
    }

    /**
     * 设置进度条文本
     */
    public void setProgressLabel(Label progressLabel) {
        this.progressLabel = progressLabel;
    }

    public Label getProgressLabel() {
        return this.progressLabel;
    }

    /**
     * 更新填充颜色渐变
     *
     * @param startColor 起始颜色
     * @param endColor   结束颜色
     */
    public void updateGradient(Color startColor, Color endColor) {
        // 创建线性渐变，渐变方向从左到右，平铺模式，起始颜色，结束颜色
        this.fillPaint = new LinearGradient(
                0, 0, 1, 0,
                true, CycleMethod.NO_CYCLE,
                new Stop(0.0, startColor),
                new Stop(1.0, endColor)
        );
        // 请求重新布局以应用新渐变
        requestLayout();
    }

    /**
     * 默认渲染实现
     * <p>
     * 绘制一个简单的进度条，背景为灰色，进度部分为指定颜色或渐变。
     *
     * @param gc     图形上下文
     * @param width  进度条宽度
     * @param height 进度条高度
     */
//    private void renderDefault(GraphicsContext gc, double width, double height) {
//        // 清除画布
//        gc.clearRect(0, 0, width, height);
//        // 绘制背景
//        gc.setFill(Color.gray(0.9));
//        // 圆角矩形
//        gc.fillRoundRect(0, 0, width, height, height, height);
//        // 计算进度条宽度
//        double progressWidth = width * getProgress();
//        // 绘制进度部分
//        // 使用渐变或默认颜色
//        gc.setFill(fillPaint != null ? fillPaint : Color.DODGERBLUE);
//        // 圆角矩形
//        gc.fillRoundRect(0, 0, progressWidth, height, height, height);
//    }

    /**
     * 默认渲染策略
     */
    private static final RenderStrategy DEFAULT_RENDER_STRATEGY = (canvas, width, height, progress) -> {
        GraphicsContext gc = canvas.getGraphicsContext2D();
        gc.clearRect(0, 0, width, height);

        // 绘制背景
        gc.setFill(Color.rgb(240, 240, 240));
        gc.fillRoundRect(0, 0, width, height, height, height);

        // 绘制渐变进度条
        double progressWidth = width * progress;
        LinearGradient gradient = new LinearGradient(
                0, 0, 1, 0,
                true, CycleMethod.NO_CYCLE,
                new Stop(0.0, Color.DODGERBLUE),
                new Stop(1.0, Color.ORANGE)
        );
        gc.setFill(gradient);
        gc.fillRoundRect(0, 0, progressWidth, height, height, height);

        // 添加动态效果（例如：白色条纹）
        if (progress > 0) {
            gc.setStroke(Color.WHITE);
            gc.setLineWidth(2);
            for (double x = 0; x < progressWidth; x += 10) {
                gc.strokeLine(x, 0, x + 5, height);
            }
        }
    };

}
